home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / cug190.zip / POP.C < prev    next >
Text File  |  1985-11-15  |  17KB  |  807 lines

  1. /******************************************************************
  2.     pop.c, the operand field parser...
  3. */
  4.  
  5. /*        (C) Copyright 1982 Steve Passe        */
  6. /*        All Rights Reserved                    */
  7.  
  8. /* version 1.00 */
  9. /* created 11/8/82 */
  10.  
  11. /* version 1.01
  12.  
  13.     8/30/83    modified for Aztec ver. 1.05g    smp
  14.     12/23/83 modified '*' to evaluate according to rorg smp
  15.  
  16. */
  17.  
  18. /* begincode */
  19.  
  20. /* includes */
  21.  
  22. #define AZTECZII 1
  23.  
  24. #ifndef AZTECZII
  25. #include <stdio.h>
  26. #else
  27. #include "stdio.h"                                /* with aztecII compiler */
  28. #endif
  29.  
  30. #include "b:as68.h"
  31.  
  32. #define RTERM        0x0100
  33. #define SLASH        0x0101
  34. #define HYPHEN        0x0102
  35.  
  36. #define PC_VALUE    0x0103
  37. #define IMD            0x0104
  38. #define COMMA        0x0105
  39. #define POINT        0x0106
  40. #define VALUE        0x0107
  41. #define LVALUE        0x0108
  42. #define FWRD_REF     0x0109
  43.  
  44. #define TOP            0x0200
  45. #define BOTTOM        0x0201
  46. #define LP            0x0202
  47. #define RP            0x0203
  48. #define PLUS        0x0204
  49. #define MINUS        0x0205
  50. #define MULT        0x0206
  51. #define DIV            0x0207
  52. #define LAND        0x0208
  53. #define LOR            0x0209
  54. #define LSHIFT        0x020a
  55. #define RSHIFT        0x020b
  56. #define NEGATE        0x020c
  57. #define LIM_C        1
  58. #define LM_C        2
  59. #define RXP            0x0303            /* signals a forced short address */
  60.  
  61. /* externals */
  62.  
  63. extern struct _oprnd op1, op2;            /* structs to hold operand val */
  64. extern struct _symbol *symtbl;
  65. extern char pass;
  66. extern long loc_counter;
  67. extern FLAG abs_long;                    /* default to absolute long add.*/
  68. extern FLAG rorg;
  69. extern char statement[STMNT_SIZE];        /* statement line buffer */
  70. extern char *opfld_ptr;
  71. extern long lex_val;
  72. extern char *p;
  73. static FLAG lv;
  74.  
  75. unsigned reg_num;
  76. int last_typ;
  77.  
  78. long val_stk[10] = {0L};
  79. int oprtr_stk[10] = {BOTTOM};
  80. int val_sp;
  81. int oprtr_sp;
  82.  
  83. op_eval(op)
  84. struct _oprnd *op;
  85. {
  86. /**    register int r; */
  87.     int shorty = NULL;                    /* force short address this line */
  88.     long val_push();
  89.  
  90.     op->_long_val = op->_inxl = op->_rel_lbl = NULL;
  91.     op->_typ = last_typ = NULL;
  92.     op->_regtyp = op->_iregtyp = op->_reg = op->_ireg = NULL;
  93.     oprtr_sp = val_sp = 0;
  94.     reg_num = NULL;
  95.     switch (*opfld_ptr) {
  96.     case '\t':
  97.     case '\n':
  98.     case ' ':
  99.     case NULL:
  100.         return (op->_typ = _none);
  101.     case ',':
  102.         ++opfld_ptr;
  103.     }
  104. top:
  105.     switch (/**r =**/ op_scan(op)) {
  106.     case COMMA:
  107.     case NULL:                /* determine operand type, finalize values in op */
  108.         reduce(TOP);        /* get into one value */
  109.         switch (op->_typ) {
  110.         case _imd:
  111.             op->_data = val_stk[1];
  112.             return _imd;
  113.         case _reglst:
  114.             return _reglst;
  115.         default:
  116.             if (abs_long) op->_long_val = TRUE;
  117.             if (shorty) op->_long_val = FALSE;    /* shorty overrides abs_long
  118.                                             AND long values in expression */
  119.             op->_addr = val_stk[1];
  120.             if (!op->_long_val && pass == 2) { /* pass 2/short, check range */
  121.                 if (op->_addr & ~0xffff) {
  122.                     op->_addr = 0;
  123.                     return (op->_typ = LBL_RANGE);
  124.                 }
  125.             }
  126.             return (op->_typ = _address);
  127.         }
  128.     case PLUS:
  129.         reduce(PLUS);
  130.         break;
  131.     case MINUS:
  132.         reduce(MINUS);
  133.         break;
  134.     case MULT:
  135.         reduce(MULT);
  136.         break;
  137.     case DIV:
  138.         reduce(DIV);
  139.         break;
  140.     case LAND:
  141.         reduce(LAND);
  142.         break;
  143.     case LOR:
  144.         reduce(LOR);
  145.         break;
  146.     case LSHIFT:
  147.         reduce(LSHIFT);
  148.         break;
  149.     case RSHIFT:
  150.         reduce(RSHIFT);
  151.         break;
  152.     case NEGATE:
  153.         reduce(NEGATE);
  154.         break;
  155.     case RXP:
  156.         reduce(RP);
  157.         if (val_sp != 1) return (op->_typ = OPRND_EVAL);
  158.         shorty = TRUE;
  159.         break;
  160.     case RP:
  161.         reduce(RP);
  162.         break;
  163.     case LP:
  164.         oprtr_push(LP);
  165.         break;
  166.     case PC_VALUE:
  167.         if (rorg) op->_rel_lbl = TRUE;
  168.         val_push(loc_counter);
  169.         break;
  170.     case IMD:
  171.         op->_typ = _imd;
  172.         break;
  173.     case LVALUE:
  174.         op->_long_val = TRUE;
  175.     case VALUE:
  176.         val_push(lex_val);
  177.         break;
  178.     case FWRD_REF:
  179. /** op->_forward = TRUE; ? */
  180.         val_push(lex_val);
  181.         break;
  182.     case _an:
  183.         return (op->_typ = _an);
  184.     case _dn:
  185.         return (op->_typ = _dn);
  186.     case _pd_ani:
  187.         return (op->_typ = _pd_ani);
  188.     case _ani_pi:
  189.         return (op->_typ = _ani_pi);
  190.     case _ani:
  191.         if (val_sp == 0) {
  192.             return (op->_typ = _ani);
  193.         }
  194.         if (reduce(TOP) != 1) return (op->_typ = OPRND_EVAL);
  195.         op->_displ = val_stk[1];
  196.         return (op->_typ = _d16_ani);
  197.     case _pc:
  198.         if (reduce(TOP) != 1) return (op->_typ = OPRND_EVAL);
  199.         op->_displ = val_stk[1];
  200.         return (op->_typ = (op->_iregtyp ? _labeli : _label));
  201. /**        return (op->_typ = _labeli); **/
  202.     case _an_inx:
  203.         if (reduce(TOP) != 1) return (op->_typ = OPRND_EVAL);
  204.         op->_displ = val_stk[1];
  205.         return (op->_typ = _d8_anx);
  206.     case _ccr:        return (op->_typ = _ccr);
  207.     case _sr:        return (op->_typ = _sr);
  208.     case _usp:        return (op->_typ = _usp);
  209.     case _reglst:    return (op->_typ = _reglst);
  210.  
  211.     case ERROR:
  212.     default:
  213.         return (op->_typ = OPRND_EVAL);
  214.     }
  215.     goto top;
  216. }
  217.  
  218. reduce(tkn)
  219. int tkn;
  220. {
  221.     long val_push(), val_pop();
  222.     long temp;
  223.  
  224.     while (oprtr_stk[oprtr_sp] >= (tkn & ~1)) {
  225.         switch (oprtr_stk[oprtr_sp--]) {
  226.         case PLUS:
  227.             val_push(val_pop() + val_pop());
  228.             continue;
  229.         case MINUS:
  230.             temp = val_pop();
  231.             val_push(val_pop() - temp);
  232.             continue;
  233.         case MULT:
  234.             val_push(val_pop() * val_pop());
  235.             continue;
  236.         case DIV:
  237.             temp = val_pop();
  238.             val_push(val_pop() / temp);
  239.             continue;
  240.         case LAND:
  241.             val_push(val_pop() & val_pop());
  242.             continue;
  243.         case LOR:
  244.             val_push(val_pop() | val_pop());
  245.             continue;
  246.         case LSHIFT:
  247.             temp = val_pop();
  248.             val_push(val_pop() << temp);
  249.             continue;
  250.         case RSHIFT:
  251.             temp = val_pop();
  252.             val_push(val_pop() >> temp);
  253.             continue;
  254.         case NEGATE:
  255.             val_push(-1 * val_pop());
  256.             continue;
  257.         case LP :
  258.             return val_sp;
  259.         case BOTTOM:
  260.             ++oprtr_sp;
  261.             return val_sp;
  262.         }
  263.     }
  264.     oprtr_push(tkn);
  265.     return val_sp;
  266. }
  267.  
  268. long
  269. val_push(l)
  270. long l;
  271. {
  272.     return (val_stk[++val_sp] = l);
  273. }
  274.  
  275. long
  276. val_pop()
  277. {
  278.     return (val_stk[val_sp--]);
  279. }
  280.  
  281. oprtr_push(t)
  282. int t;
  283. {
  284.     return (oprtr_stk[++oprtr_sp] = t);
  285. }
  286.  
  287. oprtr_pop()
  288. {
  289.     return (oprtr_stk[oprtr_sp--]);
  290. }
  291.  
  292. op_scan(op)
  293. struct _oprnd *op;
  294. {
  295.     int typ, len;
  296.     char s[32];
  297.     long _dtol(), _htol(), _btol(), _actol();
  298.  
  299.     p = opfld_ptr;
  300.  
  301.     if (typ = reg_scan(op)) {
  302.         opfld_ptr = p;
  303.         if (typ > 0) return typ;
  304.         goto foops;
  305.     }
  306.     switch (*opfld_ptr++) {
  307.     case '-':    /* choose between NEGATE and MINUS */
  308.         switch (last_typ) {
  309.         case NULL:
  310.         case IMD:
  311.         case LP:
  312.         case PLUS:
  313.         case MINUS:
  314.         case MULT:
  315.         case DIV:
  316.         case LAND:
  317.         case LOR:
  318.             return (last_typ = NEGATE);
  319.         case RXP:
  320.         case LSHIFT:
  321.         case RSHIFT:
  322.             goto foops;
  323.         default:
  324.             return (last_typ = MINUS);
  325.         }
  326.     case '(':                                        /* (            */
  327.         return (last_typ = LP);
  328.     case ')':                                        /* )            */
  329.         if (opfld_ptr[0] == '.'                        /* ).s            */
  330.             && (opfld_ptr[1] == 's' || opfld_ptr[1] == 'S')) {
  331.             p = (opfld_ptr += 2);        /* skip the '.s' */
  332.             return (last_typ = RXP);
  333.         }
  334.         else return (last_typ = RP);
  335.     case '#':                                        /* #            */
  336.         return (last_typ = IMD);
  337.     case '$':                                        /* $            */
  338.         lex_val = _htol();
  339.         return (last_typ = (lv) ? LVALUE : VALUE);
  340.     case '%':                                        /* %            */
  341.         lex_val = _btol();
  342.         return (last_typ = VALUE);
  343.     case '*':                                        /* *            */
  344.         switch (last_typ) {
  345.         case NULL:
  346.         case IMD:
  347.         case LP:
  348.         case PLUS:
  349.         case MINUS:
  350.         case MULT:
  351.         case DIV:
  352.         case IMD:
  353.         case LAND:
  354.         case LOR:
  355.         case LSHIFT:
  356.         case RSHIFT:
  357.             return (last_typ = PC_VALUE);
  358.         case RXP: goto foops;
  359.         default:
  360.             return (last_typ = MULT);
  361.         }
  362.     case '/':                                        /* /            */
  363.         return (last_typ = DIV);
  364.     case '+':                                        /* +            */
  365.         return (last_typ = PLUS);
  366.     case '&':                                        /* &            */
  367.         return (last_typ = LAND);
  368.     case '!':                                        /* !            */
  369.         return (last_typ = LOR);
  370.     case '>':                                        /* >...            */
  371.         if (*opfld_ptr++ != '>') goto foops;        /* >FAIL        */
  372.         return (last_typ = RSHIFT);                    /* >>            */
  373.     case '<':                                        /* <...            */
  374.         if (*opfld_ptr++ != '<') goto foops;        /* <FAIL        */
  375.         return (last_typ = LSHIFT);                    /* <<            */
  376.     case '\'':                                        /* '            */
  377.         lex_val = _actol();
  378.         return (last_typ = VALUE);
  379.     case ',':                                        /* ,            */
  380.         return (last_typ = COMMA);
  381.     case ' ':
  382.     case '\t':
  383.     case '\n':
  384.         --opfld_ptr;
  385.         return (last_typ = NULL);
  386.     }
  387.     --opfld_ptr;
  388.  
  389. /* look for decimal number */
  390.     if (*opfld_ptr >= '0' && *opfld_ptr <= '9') {
  391.         lex_val = _dtol();
  392.         return (last_typ = (lv) ? LVALUE : VALUE);
  393.     }
  394.     p =